package skin
{
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.utils.Dictionary;

	/**
	 *皮肤基类,该类不能实例化,必须由子类继承后使用
	 * @author 张进辉
	 * 
	 */	
	public class SkinBase extends Sprite
	{
		/**是否为矢量图,如果为矢量图在调整大小时将重绘*/
		public var isVector:Boolean = false;
		
		/**高度*/
		protected var _hh:Number;
		/**宽度*/
		protected var _ww:Number;
		
		
		/**皮肤所有的状态*/
		private var _states:Array=[];
		
		/**状态对应的皮肤层*/
		private var _layers:Dictionary = new Dictionary();
		
		/**当前状态*/
		private var _currentState:String;
		
		/**皮肤附着的组件*/
		private var _hostCompent:Sprite;
		
		
		public function SkinBase()
		{
			super();
			mouseChildren = mouseEnabled = false;
			addEventListener(Event.ADDED_TO_STAGE,addedHandler);
		}
		
		/**添加到舞台事件*/
		private function addedHandler(event:Event):void
		{
			removeEventListener(Event.ADDED_TO_STAGE,addedHandler);
			addEventListener(Event.ENTER_FRAME,nextFrameHandler);
		}		
		
		/**初始化*/
		private function nextFrameHandler(event:Event):void
		{
			removeEventListener(Event.ENTER_FRAME,nextFrameHandler);
			initialize();
		}
		
		/**
		 * 皮肤拥有的状态,该操作将会自动创建皮肤层
		 * */
		public final function set states(value:Array):void
		{
			if(!value) return;
			
			_states = value;
			for each (var stateName:String in _states) 
			{
				createLayer(stateName);
			}
				
			skinCompleted();
		}
		/**
		 * @private
		*/
		public final function get states():Array
		{
			return _states;
		}
		
		/**
		 *绘制皮肤层 
		 * @param stateName
		 * @return 
		 * 
		 */		
		private function createLayer(stateName:String):Sprite
		{
			var layer:Sprite = new Sprite();
			layer.visible = (_currentState == stateName);
			if(!_currentState)//设定默认显示的皮肤
			{
				_currentState = stateName;
				layer.visible = true;
			}
			addChild(layer);
			_layers[stateName] = layer;
			createSkin(stateName,layer);//绘制该皮肤内容
			
			return layer;
		}
		
		/**皮肤当前的状态*/
		public final function set currentState(value:String):void
		{
			if(!value || _states.length == 0) return;
			
			if(_currentState != value)
			{
				_currentState = value;
				
				for(var layerName:String in _layers) 
				{
					Sprite(_layers[layerName]).visible = (value == layerName);
				}
				
				stateChange();//回调
			}
			else//确保该方法生效
			{
				if(Sprite(_layers[layerName]).visible == false)
					Sprite(_layers[layerName]).visible = true;
			}
		}
		/**
		 * @private
		 * 
		 */		
		public final function get currentState():String
		{
			return _currentState;
		}
		
		/**皮肤附着的组件,设定后不允许更改*/
		public final function set hostCompent(value:Sprite):void
		{
			if(_hostCompent) return;
			
			_hostCompent = value;
			hostReady();
		}
		public final function get hostCompent():Sprite
		{
			return _hostCompent;
		}
		
		/**
		 * 创建各个状态下的皮肤内容,子类必须覆盖此方法,但无需调用该方法
		 * @param stateName: 状态名称,由states方法设定的
		 * @param container: 该状态对应的皮肤容器,可以在容器内添加自定义的皮肤
		 * 
		 */		
		protected function createSkin(stateName:String,container:Sprite):void
		{
			//该状态下添加的内容
		}
		
		/**
		 *初始化完成 
		 * 
		 */		
		protected function skinCompleted():void
		{
			
		}
		
		/**
		 *状态发生变化时的回调 
		 */		
		protected function stateChange():void
		{
			
		}
		
		/**初始化,由子类覆盖,无需调用.可以在此执行状态设置*/
		protected function initialize():void
		{
			
		}
		
		/**主机组件设定完成后可对其进行操作,如注册事件*/
		protected function hostReady():void
		{
			
		}
		
		/**
		 *重绘 
		 * 
		 */		
		private function reDraw():void
		{
			for each (var stateName:String in _states) 
				createSkin(stateName,_layers[stateName]);
		}
		
		override public function get height():Number
		{
			return _hh;
		}
		
		override public function set height(value:Number):void
		{
			if(value <= 0) return;
			if(value != _hh)
			{
				_hh = value;
				if(isVector)
					reDraw();
			}
		}
		
		override public function get width():Number
		{
			return _ww;
		}
		
		override public function set width(value:Number):void
		{
			if(value <= 0) return;
			
			if(value != _ww)
			{
				_ww = value;
				if(isVector)
					reDraw();
			}
		}
		
		public function destroy():void
		{
			_hostCompent = null;
		}
	}
}